import re
import time
from queue import Queue
from threading import Thread

from src.utils.method import Method
from src.datatype import ProcessLog, RobotMsg
from src.user_data import UserData
from src.network.client import Client


class Logger:
    def __init__(self, conf: UserData):
        """日志管理器"""
        self.__conf = conf
        self.__ini = self.__conf.iniCls
        # 内部参数
        self.__log_queue = Queue()
        self.__robot_log = Queue()
        self.__cmd_queue = Queue()
        self.__report_log = Queue()
        self.__header_regs: list = ["(?<=\\[Server]).*", "(?<=\\[INFO]).*",
                                    "(?<=\\[INFO ]).*", "(?<=\\[Server thread/INFO]).*"]

    def __do_reg_print(self) -> None:
        """正则匹配处理"""
        while True:
            log: ProcessLog = self.__log_queue.get()
            self.__shield_print(log)
            # 用户设定的匹配
            for reg in self.__ini.robot_re_list:
                try:
                    # 符合过滤列表则过滤内容
                    need_filter = False
                    for filter_reg in reg.get("过滤列表", []):
                        if re.search(filter_reg, log.text):
                            need_filter = True
                            break
                    if need_filter:
                        continue
                    # 匹配成功才进行后续操作
                    res = re.findall(reg["正则"], log.text)
                    if not res:
                        continue
                    # 文本追加处理
                    addon_num: int = reg.get("输出追加行数", 0)
                    cmd: str = reg.get("执行命令", "")
                    msg: str = reg.get("返回消息格式", "")
                    # 广播任务处理
                    report_addr: str = reg.get("广播地址")
                    report_format: str = reg.get("广播格式", "")
                    if report_addr:
                        self.__report_log.put((report_addr, log.text, report_format))
                    # 返回消息与执行命令处理
                    addon_lines = self.__addon_lines("", addon_num)
                    if msg:
                        msg = Method.deal_placeholder(msg, res, log.text)
                        self.__cmd_queue.put("group " + msg + addon_lines)
                    if cmd:
                        cmd = Method.deal_placeholder(cmd, res, log.text)
                        self.__cmd_queue.put(cmd + addon_lines)
                except Exception as err:
                    print(f"[DLS][WARN][REG] 错误的匹配: {reg} 原因: {err}")

    def __do_report_task(self) -> None:
        """处理播报任务"""
        while True:
            task: tuple = self.__report_log.get()
            time.sleep(0.2)
            Client.send_raw(task[0], task[1], task[2])

    def __addon_lines(self, msg: str, num: int) -> str:
        """根据数量追加输出"""
        for _ in range(num):
            logx: ProcessLog = self.__log_queue.get()
            self.__shield_print(logx)
            # 剔除前缀
            pla: str = logx.text
            for header_reg in self.__header_regs:
                pla = Method.del_info_header(header_reg, pla)
            # 不为空字符串时才追加输出
            if pla:
                msg = msg + "\n" + pla
        return msg

    def __shield_print(self, log: ProcessLog) -> None:
        """部分屏蔽的输出打印"""
        for shield_reg in self.__ini.output_shield:
            if re.search(shield_reg, log.text):
                return
        print(log.raw_text)

    def add_log(self, raw_text: str) -> None:
        """添加消息至日志队列"""
        self.__log_queue.put(ProcessLog(raw_text))

    def add_robot_msg(self, text: str) -> None:
        """添加消息至机器人日志队列"""
        if self.__ini.robot_on and text:
            self.__robot_log.put(RobotMsg(text))

    def get_robot_msg(self) -> RobotMsg:
        """获取合并机器人消息"""
        size = self.__robot_log.qsize()
        combine_msg = RobotMsg()
        for _ in range(size):
            log: RobotMsg = self.__robot_log.get()
            combine_msg += log
        return combine_msg

    def get_cmd_list(self) -> list:
        """取出cmd队列返回内容列表"""
        cmd_list = []
        size = self.__cmd_queue.qsize()
        for _ in range(size):
            cmd: str = self.__cmd_queue.get()
            cmd_list.append(cmd)
        return cmd_list

    def start(self) -> None:
        """启动日志管理器"""
        thx = Thread(target=self.__do_reg_print, daemon=True)
        thx.start()
        thy = Thread(target=self.__do_report_task, daemon=True)
        thy.start()

    def reload(self) -> None:
        """重载配置"""
        self.__ini = self.__conf.iniCls
